#import "ARLStringUtils.h"
@implementation NSString (ARLStringUtils)

- (NSString*)arl_encodeBase64{
    return [ARLStringUtils base64StringFromString:self];
}

- (NSString*)arl_decodeBase64{
    return [ARLStringUtils decodeFromBase64String:self];
}
@end

@implementation ARLStringUtils
#pragma mark (●ﾟωﾟ●) base64转换 (●ﾟωﾟ●)

+(NSString*)base64StringFromString:(NSString*)originStr{
    NSData *nsData =[ARLStringUtils dataFromString:originStr];
    NSString *base64Encoded = [nsData base64EncodedStringWithOptions:0];
    return base64Encoded;
}

+(NSString*)base64webSafeStringFromString:(NSString*)originStr{
    NSString* base64Encoded = [ARLStringUtils base64StringFromString:originStr];
    base64Encoded = [[base64Encoded stringByReplacingOccurrencesOfString:@"+" withString:@"-"] stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
    return base64Encoded;
}

+(NSData*)dataFromString:(NSString*)originStr{
    NSData *nsData = [originStr dataUsingEncoding:NSUTF8StringEncoding];
    return nsData;
}

+(NSString*)decodeFromBase64String:(NSString*)base64EncodedStr{
    NSData *nsdataFromBase64String = [[NSData alloc] initWithBase64EncodedString:base64EncodedStr options:0];
    NSString *base64Decoded = [[NSString alloc] initWithData:nsdataFromBase64String encoding:NSUTF8StringEncoding];
    return base64Decoded;
}

+(NSString*)decodeFromBase64WebSafeString:(NSString*)base64EncodedStr{
    base64EncodedStr = [[base64EncodedStr stringByReplacingOccurrencesOfString:@"-" withString:@"+"] stringByReplacingOccurrencesOfString:@"_" withString:@"/"];
    NSString *base64Decoded = [ARLStringUtils decodeFromBase64String:base64EncodedStr];
    return base64Decoded;
}

#pragma mark (●ﾟωﾟ●) NSDictionary，NSArray和String转换 (●ﾟωﾟ●)
+(NSDictionary*)dictionaryFromJSONString:(NSString*)jsonStr{
    NSError * error = nil;
    NSData * jsonData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
    if (!jsonData) {
        return nil;
    }
    NSDictionary* jsonDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
    
    if(error||![jsonDic isKindOfClass:[NSDictionary class]]){
        return nil;
    }else{
        return jsonDic;
    }
}

+(id)objectFromJSONString:(NSString*)jsonStr{
    NSError * error = nil;
    NSData * jsonData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
    id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
    if(error){
        return nil;
    }else{
        return jsonObject;
    }
}


+(NSArray*)arrayFromJSONString:(NSString*)jsonStr{
    NSError * error = nil;
    NSData * jsonData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
    NSArray* array = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
    if(error||![array isKindOfClass:[NSArray class]]){
        return nil;
    }else{
        return array;
    }
}


+(NSString*)stringFromDictionary:(NSDictionary*)dict{
    if (dict == nil || ![dict isKindOfClass:[NSDictionary class]] || dict.count == 0 || ![NSJSONSerialization isValidJSONObject:dict])
        return nil;
    NSError * error = nil;
    NSString* jsonStr = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:dict options:0 error:&error]encoding:NSUTF8StringEncoding];
    if(error){
        return nil;
    }else{
        return jsonStr;
    }
}

//NSArray to jsontStr
+(NSString*)stringFromArray:(NSArray*)array{
    NSError * error = nil;
    if (array == nil || ![NSJSONSerialization isValidJSONObject:array]) {
        return nil;
    }
    NSString* jsonStr = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:array options:NSJSONWritingPrettyPrinted error:&error]encoding:NSUTF8StringEncoding];
    if(error){
        return nil;
    }else{
        return jsonStr;
    }
}

+(NSString*)stringFromData:(NSData*)data{
    NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    
    return string;
}



+ (NSString *)encodeURIComponent:(NSString*)urlStr {
    
    NSString *encodedUrl = nil;
    if (@available(iOS 9.0, *)) {
//        NSMutableCharacterSet *set = [NSMutableCharacterSet new];
//        [set formUnionWithCharacterSet:([NSMutableCharacterSet alphanumericCharacterSet])];
//        [set formUnionWithCharacterSet:([NSMutableCharacterSet characterSetWithCharactersInString:@"-_.!~*'()"])];
//        encodedUrl = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:set];
        encodedUrl = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[[NSCharacterSet characterSetWithCharactersInString:@"!*'();:@&=+$,/?%#[]^"] invertedSet]];
    }else {
        encodedUrl = (NSString *) CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)urlStr, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]^", kCFStringEncodingUTF8));
    }
    
    return encodedUrl;
    
}




//对齐web标准，如果有不同可以增加字符
+(NSString*)encodeUrl:(NSString*)urlStr{
    NSString *encodedUrl = nil;
//    if (@available(iOS 9.0, *)) {
        //        encodedUrl = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLQueryAllowedCharacterSet];
        encodedUrl = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[[NSCharacterSet characterSetWithCharactersInString:@"!*'();$,%[]{}^"] invertedSet]];
//    }else {
//        encodedUrl = (NSString *)
//        CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
//                                                                  (CFStringRef)urlStr, NULL,(CFStringRef)@"!*'();$,%[]{}^",kCFStringEncodingUTF8));
//    }
    
    return encodedUrl;
}

+(NSString*)decodeUrl:(NSString*)encodedUrl{
    NSString* decodedString = [encodedUrl stringByRemovingPercentEncoding];
//    NSString *decodedString  = (__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL,(__bridge CFStringRef)encodedUrl,
//                                                                                                                     CFSTR(""),
//                                                                                                                     CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
    return decodedString;
}




+(BOOL)isEmpty:(NSString*)str{
    if(str==nil||[str isEqualToString:@""]){
        return true;
    }else{
        return false;
    }
}
+(BOOL)isNotEmpty:(NSString*)str{
    return ![ARLStringUtils isEmpty:str];
}


+(NSString*)formatSpaceWithUnderline:(NSString*)fmtStr{
    return [fmtStr stringByReplacingOccurrencesOfString:@" " withString:@"_"];
}


+(int)hashCode:(NSString*)targetStr {
    int hash = 0;
    for (int i = 0; i<[targetStr length]; i++) {
        NSString *s = [targetStr substringWithRange:NSMakeRange(i, 1)];
        char *unicode = (char *)[s cStringUsingEncoding:NSUnicodeStringEncoding];
        int charactorUnicode = 0;
        
        size_t length = strnlen(unicode, 4);
        for (int n = 0; n < length; n ++) {
            charactorUnicode += (int)((unicode[n] & 0xff) << (n * sizeof(char) * 8));
        }
        hash = hash * 31 + charactorUnicode;
    }
    
    return hash;
}


+ (NSString *)dataToHexString:(NSData *)data {
    if (!data || [data length] == 0) {
        return @"";
    }
    NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
    
    [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
        unsigned char *dataBytes = (unsigned char*)bytes;
//        NSInteger bi = dataBytes;
        for (NSInteger i = 0; i < byteRange.length; i++) {
            
            
            NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
            if ([hexStr length] == 2) {
                [string appendString:hexStr];
            } else {
                [string appendFormat:@"0%@", hexStr];
            }
        }
    }];
    
    return string;
}


+ (NSString *)trimString:(NSString*)str {
    NSCharacterSet *set = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    return [str stringByTrimmingCharactersInSet:set];
}
@end
